#include <iostream>
#include <thread>
#include <string>
#include <fstream>
#include <mutex>

/*
使用std::unique_lock加锁，目的是提高灵活性，为不需要加锁的代码解锁
*/

class LogFile
{
    std::mutex m_mutex;
    std::ofstream f;  //被m_mutex保护的对象
public:
    LogFile(/* args */){
        f.open("log.txt");
    };
    void shared_print(std::string id, int value){
        //std::unique_lock<std::mutex> locker(m_mutex);
        //std::defer_lock表示m_mutex不会被locker锁住，可以自己选择加锁和解锁的位置
        std::unique_lock<std::mutex> locker(m_mutex,std::defer_lock);
        //...
        locker.lock();
        f << "From " << id << ": " <<value << std::endl;
        locker.unlock();
        //...
        locker.lock();
    }
};



void function_1() {
    std::cout << "www.work" << std::endl;

}

class Factor
{
public:
    //void operator()(std::string& msg)
    void operator()(std::string msg)
    {
        std::cout << "from t1:" << msg << std::endl;
        msg = "I love learning";
        
    }
};





int main() {
    //std::thread t1(function_1);  //t1线程开始运行

    //Factor fct;
    //std::thread t1(fct);  //使用对象
    std::string s = "I love workworkwork";
    // std::thread t1((Factor()), std::ref(s));  //直接使用类   添加参数  引用传递
    //                                           //这里不使用std::ref()将还是值传递
    //                                           //但是主线程与t1线程内存分享将导致数据竞争的问题
    std::thread t1((Factor()), std::move(s));   //将s字符串从主线程移动到子线程，安全高效
    // try {
    //         std::cout << "from main:" << s << std::endl;
    // }
    // catch (...){
    //     t1.join();
    //     throw;
    // }

    t1.join();
    std::cout << "666";
    return 0;
}